import React, { useCallback, useRef, useMemo, useEffect, useState } from 'react';
import ReactFlow, {
  Background,
  Controls,
  MiniMap,
  useNodesState,
  useEdgesState,
  addEdge,
  getBezierPath,
  Panel,
} from 'reactflow';
import 'reactflow/dist/style.css';
import { convertJsonToNodes, createStructureEdges } from '../utils/jsonUtils';
import { TextField, Popover } from '@mui/material';

// 简化 edgeStyles 定义
const edgeStyles = {
  labelStyle: {
    fill: '#333',
  },
  labelBgStyle: {
    fill: '#fff',
    rx: 4,
    ry: 4,
  },
};

// 定义自定义边类型组件
const StructureEdge = ({
  id,
  sourceX,
  sourceY,
  targetX,
  targetY,
  sourcePosition,
  targetPosition,
  style = {},
  data,
}) => {
  // 计算节点的中间位置
  const sourceNode = document.getElementById(id.split('-').pop());
  const targetNode = document.getElementById(id.split('-').pop());
  
  // 获取节点高度，如果无法获取则使用默认值
  const nodeHeight = sourceNode?.offsetHeight || 40;
  
  // 计算起始和结束点的中间位置
  const startY = sourceY + (nodeHeight / 2);
  const endY = targetY + (nodeHeight / 2);

  const [edgePath] = getBezierPath({
    sourceX,
    sourceY: startY,
    sourcePosition,
    targetX,
    targetY: endY,
    targetPosition,
  });

  return (
    <path
      id={id}
      style={{
        ...style,
        strokeWidth: 1,
        stroke: '#1a73e8',
      }}
      className="react-flow__edge-path"
      d={edgePath}
    />
  );
};

// 修改 StructureSiblingEdge 组件
const StructureSiblingEdge = ({
  id,
  sourceX,
  sourceY,
  targetX,
  targetY,
  sourcePosition,
  targetPosition,
  style = {},
}) => {
  // 计算控制点，使连线更平滑
  const midY = (sourceY + targetY) / 2;
  
  const path = `M${sourceX} ${sourceY} 
               C${sourceX} ${midY} 
                ${targetX} ${midY} 
                ${targetX} ${targetY}`;

  return (
    <path
      id={id}
      style={{
        ...style,
        strokeWidth: 1,
        stroke: '#1a73e8',
        strokeDasharray: '3 3',
      }}
      className="react-flow__edge-path"
      d={path}
    />
  );
};

// 扩展颜色映射配置
const inputColors = {
  A: { color: '#1a73e8', light: '#e8f0fe', name: 'X输入A' },
  B: { color: '#188038', light: '#e6f4ea', name: 'X输入B' },
  C: { color: '#c5221f', light: '#fce8e6', name: 'X输入C' },
  D: { color: '#9334e6', light: '#f3e8fd', name: 'X输入D' },
  E: { color: '#ea8600', light: '#fef6e6', name: 'X输入E' },
  F: { color: '#0b57d0', light: '#e6f3ff', name: 'X输入F' },
  G: { color: '#b31412', light: '#fde7e7', name: 'X输入G' },
  H: { color: '#1e8e3e', light: '#e6f4ea', name: 'X输入H' },
  I: { color: '#d93025', light: '#fce8e6', name: 'X输入I' },
  J: { color: '#8430ce', light: '#f3e8fd', name: 'X输入J' },
  K: { color: '#ea8600', light: '#fef6e6', name: 'X输入K' },
  L: { color: '#185abc', light: '#e8f0fe', name: 'X输入L' },
  M: { color: '#c5221f', light: '#fce8e6', name: 'X输入M' },
  N: { color: '#188038', light: '#e6f4ea', name: 'X输入N' }
};

// 添加一个辅助函数来获取默认颜色（当超出预定义颜色时使用）
const getColorScheme = (id) => {
  if (inputColors[id]) {
    return inputColors[id];
  }
  // 如果超出预定义颜色，返回一个基于字母的动态颜色
  const hue = (id.charCodeAt(0) - 65) * 25 % 360; // 基于字母生成不同的色相
  return {
    color: `hsl(${hue}, 70%, 35%)`,
    light: `hsl(${hue}, 70%, 95%)`,
    name: `X输入${id}`
  };
};

function JsonVisualizer({ xInputs, yInput, onMappingChange }) {
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
  const [selectedNodes, setSelectedNodes] = React.useState([]);
  const [isDragging, setIsDragging] = React.useState(false);
  const [edgeText, setEdgeText] = useState('');
  const [selectedEdge, setSelectedEdge] = useState(null);
  const [anchorPosition, setAnchorPosition] = useState(null);

  // 定义边类型
  const edgeTypes = React.useMemo(() => ({
    structure: StructureEdge,
    structureSibling: StructureSiblingEdge,
  }), []);

  React.useEffect(() => {
    let newNodes = [];
    let structureEdges = [];
    
    // 计算每个输入所需的最大高度
    const calculateNodeHeight = (nodes) => {
      if (!nodes || nodes.length === 0) return 0;
      const yPositions = nodes.map(node => node.position.y);
      const maxY = Math.max(...yPositions);
      const minY = Math.min(...yPositions);
      return maxY - minY + 100;
    };

    // 处理 Y 输出节点
    if (yInput && yInput.data) {
      const yPosition = 100;
      const xPosition = 800; // 设置一个固定的初始 X 位置
      
      // 添加输出标识节点
      newNodes.push({
        id: 'header-Y',
        type: 'default',
        data: { label: 'Y输出' },
        position: { x: xPosition, y: yPosition - 50 },
        style: {
          padding: '8px 12px',
          background: '#e6f4ea',
          border: '2px solid #00a651',
          borderRadius: '4px',
          fontSize: '14px',
          fontWeight: 'bold',
          color: '#00a651',
          width: 'auto',
        }
      });

      const yNodes = convertJsonToNodes(
        yInput.data,
        'result',
        null,
        { x: xPosition, y: yPosition }
      );
      newNodes = newNodes.concat(yNodes);
      
      const yEdges = createStructureEdges(yInput.data, 'result');
      structureEdges = structureEdges.concat(yEdges);
    }

    // 处理 X 输入节点
    if (xInputs && xInputs.length > 0) {
      let previousColumnHeight = 0;
      
      xInputs.forEach((input, index) => {
        const colorScheme = getColorScheme(input.id);
        const xPosition = 50 + (index * 400); // 增加水平间距
        const yPosition = previousColumnHeight + 100; // 基于前一列的高度设置起始位置
        
        // 添加输入源标识节点
        newNodes.push({
          id: `header-${input.id}`,
          type: 'default',
          data: { label: colorScheme.name },
          position: { x: xPosition, y: yPosition - 50 },
          style: {
            padding: '8px 12px',
            background: colorScheme.light,
            border: `2px solid ${colorScheme.color}`,
            borderRadius: '4px',
            fontSize: '14px',
            fontWeight: 'bold',
            color: colorScheme.color,
            width: 'auto',
          }
        });
        
        // 创建输入节点并应用对应的颜色方案
        const xNodes = convertJsonToNodes(
          input.data,
          input.id,
          null,
          { x: xPosition, y: yPosition }
        ).map(node => ({
          ...node,
          style: {
            ...node.style,
            background: colorScheme.light,
            border: `1px solid ${colorScheme.color}`,
            color: colorScheme.color,
          }
        }));
        
        // 计算当前列的高度并更新 previousColumnHeight
        const currentColumnHeight = calculateNodeHeight(xNodes);
        previousColumnHeight = Math.max(previousColumnHeight, currentColumnHeight);
        
        newNodes = newNodes.concat(xNodes);
        
        const xEdges = createStructureEdges(input.data, input.id);
        structureEdges = structureEdges.concat(xEdges.map(edge => ({
          ...edge,
          style: {
            ...edge.style,
            stroke: colorScheme.color,
          }
        })));
      });
    }

    // 设置节点通用属性
    newNodes = newNodes.map(node => ({
      ...node,
      type: 'default',
      draggable: true,
      connectable: true,
      sourcePosition: 'right',
      targetPosition: 'left',
      style: {
        ...node.style,
        padding: 10,
        borderRadius: '3px',
        width: 150,
      }
    }));

    setNodes(newNodes);
    setEdges(edges => {
      const mappingEdges = edges.filter(edge => edge.type === 'smoothstep');
      const validMappingEdges = mappingEdges.filter(edge => {
        const sourceExists = newNodes.some(node => node.id === edge.source);
        const targetExists = newNodes.some(node => node.id === edge.target);
        return sourceExists && targetExists;
      });

      return [
        ...validMappingEdges,
        ...structureEdges
      ];
    });
  }, [xInputs, yInput, setNodes, setEdges]);

  // 修改连线处理函数
  const onConnect = useCallback((params) => {
    const sourceId = params.source;
    const targetId = params.target;

    // 检查是否从 X 节点连接到 Y 节点
    const isSourceFromX = !sourceId.startsWith('result');
    const isTargetFromY = targetId.startsWith('result');

    if (!isSourceFromX || !isTargetFromY) {
      console.log('只允许从X节点连到Y节点');
      return;
    }

    // 获取源节点所属的输入组（A、B、C等）
    const inputId = sourceId.charAt(0);
    const colorScheme = getColorScheme(inputId);

    // 创建新的边，设置为实线样式
    const edge = {
      ...params,
      id: `e${sourceId}-${targetId}`,
      type: 'smoothstep',
      animated: false, // 设置为 false，不显示动画
      data: { formatter: '' },
      style: { 
        stroke: colorScheme.color,
        strokeWidth: 2,
        strokeDasharray: 'none' // 确保是实线
      },
      labelStyle: {
        ...edgeStyles.labelStyle,
        fill: colorScheme.color,
      },
      labelBgStyle: {
        ...edgeStyles.labelBgStyle,
        stroke: colorScheme.color,
        strokeWidth: 1,
      }
    };

    setEdges((eds) => {
      const newEdges = addEdge(edge, eds);
      const mappings = newEdges
        .filter(e => e.type === 'smoothstep')
        .map(e => ({
          source: e.source,
          target: e.target,
          formatter: e.data?.formatter || ''
        }));
      onMappingChange(mappings);
      return newEdges;
    });
  }, [setEdges, onMappingChange]);

  // 修改 onSelectionChange 函数
  const onSelectionChange = useCallback(({ nodes: selectedNodes, edges: selectedEdges }) => {
    if (!isDragging) {
      setSelectedNodes(selectedNodes || []);
      
      // 更新选中节点的样式
      setNodes(nds => 
        nds.map(node => ({
          ...node,
          style: {
            ...node.style,
            border: selectedNodes?.some(n => n.id === node.id) 
              ? '2px solid #1a73e8' 
              : '1px solid #777',
            boxShadow: selectedNodes?.some(n => n.id === node.id)
              ? '0 0 10px rgba(26,115,232,0.3)'
              : 'none'
          }
        }))
      );
    }
    
    // 处理边的样式，保持原有颜色
    setEdges((eds) => 
      eds.map(edge => {
        if (edge.type !== 'smoothstep') return edge;
        const inputId = edge.source.charAt(0);
        const colorScheme = getColorScheme(inputId);
        
        return {
          ...edge,
          style: {
            ...edge.style,
            stroke: selectedEdges?.some(e => e.id === edge.id) 
              ? '#ff0000'  // 选中时显示红色
              : colorScheme.color,  // 未选中时显示对应输入源的颜
            strokeDasharray: selectedEdges?.some(e => e.id === edge.id) ? '5 5' : 'none',
          }
        };
      })
    );
  }, [setEdges, setNodes, isDragging]);

  // 修改 onNodeDragStart 函数
  const onNodeDragStart = useCallback((event, draggedNode) => {
    setIsDragging(true);
    
    // 确保节点有 position 属性
    if (!draggedNode.position) {
      draggedNode.position = { x: 0, y: 0 };
    }
    
    // 如果是标题节点，初始化所有相关节点的初始位置和偏移量
    if (draggedNode.id.startsWith('header-')) {
      const inputId = draggedNode.id.split('-')[1];
      
      setNodes(nds => 
        nds.map(node => {
          if (node.id.startsWith(inputId)) {
            // 确保节点有 position 属性
            if (!node.position) {
              node.position = { x: 0, y: 0 };
            }
            return {
              ...node,
              __rf: {
                ...node.__rf,
                initialPosition: { ...node.position },
                // 计算与标题节点的相对位置
                offset: {
                  x: node.position.x - draggedNode.position.x,
                  y: node.position.y - draggedNode.position.y,
                }
              }
            };
          }
          return node;
        })
      );
    }
  }, [setNodes]);

  // 修改 onNodeDrag 函数，支持 Y 节点的整体移��
  const onNodeDrag = useCallback((event, draggedNode) => {
    // 检查是否是标题节点（header节点）
    if (draggedNode.id.startsWith('header-')) {
      const inputId = draggedNode.id.split('-')[1]; // 获取输入ID (A, B, C等 或 Y)
      
      setNodes(nds => {
        // 如果是第一次拖动，为所有相关节点保存初始位置
        const nodesWithInitialPos = nds.map(node => {
          // 对于 Y 节点，检查 result 前缀
          const shouldMove = inputId === 'Y' ? 
            node.id.startsWith('result') || node.id === draggedNode.id :
            node.id.startsWith(inputId);

          if (shouldMove) {
            if (!node.__rf?.initialPosition) {
              return {
                ...node,
                __rf: {
                  ...node.__rf,
                  initialPosition: { ...node.position },
                  offset: {
                    x: node.position.x - draggedNode.position.x,
                    y: node.position.y - draggedNode.position.y,
                  }
                }
              };
            }
            return node;
          }
          return node;
        });

        // 更新所有相关节点的位置
        return nodesWithInitialPos.map(node => {
          const shouldMove = inputId === 'Y' ? 
            node.id.startsWith('result') || node.id === draggedNode.id :
            node.id.startsWith(inputId);

          if (shouldMove) {
            return {
              ...node,
              position: {
                x: draggedNode.position.x + (node.__rf?.offset?.x || 0),
                y: draggedNode.position.y + (node.__rf?.offset?.y || 0),
              }
            };
          }
          return node;
        });
      });
    }
  }, [setNodes]);

  // 修改 onNodeDragStop 函数
  const onNodeDragStop = useCallback((event, draggedNode) => {
    setIsDragging(false);

    // 确保节点有 position 属性
    if (!draggedNode.position) {
      draggedNode.position = { x: 0, y: 0 };
    }

    // 如果是标题节点，清除所有相关节点的初始位置记录
    if (draggedNode.id.startsWith('header-')) {
      const inputId = draggedNode.id.split('-')[1];
      
      setNodes(nds => 
        nds.map(node => {
          if (node.id.startsWith(inputId)) {
            const { __rf, ...rest } = node;
            return {
              ...rest,
              position: node.position || { x: 0, y: 0 }
            };
          }
          return node;
        })
      );
      return;
    }

    // 处理普通节点的拖动逻辑
    if (selectedNodes.length > 0) {
      // 获取节点的初始位置，如果不存在���使用当前位置
      const initialPosition = draggedNode.__rf?.position || draggedNode.position;
      
      // 计算位置差异
      const dx = draggedNode.position.x - (initialPosition.x || 0);
      const dy = draggedNode.position.y - (initialPosition.y || 0);
      
      setNodes(nds => 
        nds.map(n => {
          if (selectedNodes.find(sn => sn.id === n.id)) {
            return {
              ...n,
              position: {
                x: (n.position?.x || 0) + dx,
                y: (n.position?.y || 0) + dy
              },
              style: {
                ...n.style,
                border: '1px solid #777',
                boxShadow: 'none'
              }
            };
          }
          return n;
        })
      );
    }
  }, [selectedNodes, setNodes]);

  // 修改 onKeyDown 函数
  const onKeyDown = useCallback((event) => {
    // 如果正在编辑文本（弹出框打开状态），不处理任何键盘事件
    if (Boolean(anchorPosition) || Boolean(selectedEdge)) {
      return;
    }

    if (event.key === 'Delete' || event.key === 'Backspace') {
      // 处理选中的边
      setEdges((eds) => {
        // 修改这里的过滤条件，正确处理 smoothstep 类型的边
        const remainingEdges = eds.filter(edge => 
          !(edge.selected && edge.type === 'smoothstep')
        );
        
        // 更新映射关系
        const mappings = remainingEdges
          .filter(e => e.type === 'smoothstep')
          .map(e => ({
            source: e.source,
            target: e.target,
            formatter: e.data?.formatter || ''
          }));
        onMappingChange(mappings);
        return remainingEdges;
      });

      // 处理选中的节点
      if (selectedNodes.length > 0) {
        const selectedNodeIds = selectedNodes.map(node => node.id);
        
        // 删除选中的节点及其子节点
        setNodes(nodes => nodes.filter(node => 
          !selectedNodeIds.some(id => node.id.startsWith(id))
        ));

        // 删除相关的边
        setEdges(edges => edges.filter(edge => 
          !selectedNodeIds.some(id => 
            edge.source.startsWith(id) || edge.target.startsWith(id)
          )
        ));

        // 更新映射关系
        const updatedMappings = edges
          .filter(e => e.type === 'smoothstep')
          .filter(e => !selectedNodeIds.some(id => 
            e.source.startsWith(id) || e.target.startsWith(id)
          ))
          .map(e => ({
            source: e.source,
            target: e.target,
            formatter: e.data?.formatter || ''
          }));
        onMappingChange(updatedMappings);

        // 清除选中状态
        setSelectedNodes([]);
      }
    }
  }, [setEdges, onMappingChange, selectedNodes, setNodes, edges, anchorPosition, selectedEdge]);

  // 添加处理双击事件的函数
  const onEdgeDoubleClick = useCallback((event, edge) => {
    // 只处理映射边（smoothstep类型）
    if (edge.type !== 'smoothstep') return;

    const rect = event.target.getBoundingClientRect();
    setSelectedEdge(edge);
    setEdgeText(edge.data?.formatter || '');
    setAnchorPosition({
      top: rect.top + window.scrollY + rect.height / 2,
      left: rect.left + window.scrollX + rect.width / 2,
    });
  }, []);

  // 添加处理文本编辑的函数
  const handleTextChange = (event) => {
    setEdgeText(event.target.value);
  };

  // 添加处理编辑完成的函数
  const handleTextSubmit = () => {
    if (selectedEdge) {
      setEdges((eds) => {
        const newEdges = eds.map(e => {
          if (e.id === selectedEdge.id) {
            return {
              ...e,
              selected: false,
              data: { ...e.data, formatter: edgeText },
              label: edgeText,
              style: {
                ...e.style,
                stroke: '#00a651',
                strokeDasharray: 'none'
              }
            };
          }
          return e;
        });

        // 更新映射关系
        const mappings = newEdges
          .filter(e => e.type === 'smoothstep')
          .map(e => ({
            source: e.source,
            target: e.target,
            formatter: e.data?.formatter || ''
          }));
        onMappingChange(mappings);

        return newEdges;
      });
    }
    // 清除编辑状态
    setSelectedEdge(null);
    setAnchorPosition(null);
    setEdgeText('');
  };

  React.useEffect(() => {
    document.addEventListener('keydown', onKeyDown);
    return () => {
      document.removeEventListener('keydown', onKeyDown);
    };
  }, [onKeyDown]);

  // 修改默认边样式配置
  const defaultEdgeOptions = {
    type: 'smoothstep',
    animated: false,
    style: { 
      stroke: '#00a651', 
      strokeWidth: 2,
      strokeDasharray: 'none'
    }
  };

  return (
    <div className="json-visualizer" style={{ height: '600px', overflow: 'hidden' }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        onSelectionChange={onSelectionChange}
        onNodeDragStart={onNodeDragStart}
        onNodeDrag={onNodeDrag}
        onNodeDragStop={onNodeDragStop}
        onEdgeDoubleClick={onEdgeDoubleClick}
        edgeTypes={edgeTypes}
        fitView
        minZoom={0.1}
        maxZoom={1.5}
        defaultZoom={0.8}
        selectionKeyCode="Control"
        multiSelectionKeyCode="Control"
        selectionMode={1}
        selectionOnDrag={false}
        attributionPosition="bottom-left"
        defaultEdgeOptions={defaultEdgeOptions}
        style={{ background: '#f8f8f8' }}
      >
        <Background color="#aaa" gap={16} />
        <Controls />
        <MiniMap 
          nodeColor={n => {
            return n.id.startsWith('result') ? '#00a651' : '#1a73e8';
          }}
        />
        <Panel position="top-left" style={{ fontSize: '12px', color: '#666' }}>
          <div>提示：按Ctrl+左键可选中多个节点移动，拖动后自动取消选中，也可以单击标题节点进行移动</div>
          <div>提示：选中节点或连线后按Delete键可删除</div>
          <div>提示：拖动X节点的右侧点到Y节点的左侧点可建立连接</div>
          <div>提示：双击连线可直接添加formatter文本</div>
        </Panel>
      </ReactFlow>

      <Popover
        open={Boolean(anchorPosition)}
        anchorReference="anchorPosition"
        anchorPosition={anchorPosition}
        onClose={handleTextSubmit}
        transformOrigin={{
          vertical: 'center',
          horizontal: 'center',
        }}
      >
        <TextField
          autoFocus
          value={edgeText}
          onChange={handleTextChange}
          onKeyDown={(e) => {
            // 阻止事件冒泡，确保删除键不会触发外层的删除事件
            e.stopPropagation();
            // 如果按下 Esc 键，取消编辑
            if (e.key === 'Escape') {
              setSelectedEdge(null);
              setAnchorPosition(null);
              setEdgeText('');
            }
          }}
          onKeyPress={(e) => {
            if (e.key === 'Enter') {
              handleTextSubmit();
            }
          }}
          placeholder="输入格式化文本"
          size="small"
          sx={{ p: 1, width: '200px' }}
        />
      </Popover>
    </div>
  );
}

export default JsonVisualizer; 